/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 * Description: package about rtos_pramdisk_fs_dax
 * Author: wangzirui
 * Create: 2022-07-13
 */
#include <linux/atomic.h>
#include <linux/mm.h>
#include <linux/uio.h>
#include <linux/iomap.h>
#include <asm/pgalloc.h>
#include "rtos_pramdisk_fs_dax.h"

/*
 * Free IO remapping for pramdisk
 */
void dax_pramdisk_should_unmap(void *addr_pmfs_p, const struct block_device *bdev_p)
{
	if (addr_pmfs_p != NULL && IS_PRAMDISK(bdev_p))
		iounmap(addr_pmfs_p);
}

void ptep_get_and_clear_in_dax(struct vm_fault *vmf)
{
	pte_t *pte = NULL;
	spinlock_t *pt1 = NULL;

	pte = get_locked_pte(vmf->vma->vm_mm, vmf->address, &pt1);
	if (pte) {
		ptep_get_and_clear(vmf->vma->vm_mm, vmf->address, pte);
		pte_unmap_unlock(pte, pt1);
	}
}

vm_fault_t rtos_insert_mixed_with_pgprot(const struct block_device *bdev,
	struct vm_area_struct *vma, unsigned long vaddr, pfn_t pfn, bool mkwrite)
{
	pgprot_t old_prot;
	vm_fault_t ret;

	if (IS_PRAMDISK(bdev)) {
		old_prot = vma->vm_page_prot;
		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
	}

	if (mkwrite)
		ret = vmf_insert_mixed_mkwrite(vma, vaddr, pfn);
	else
		ret = vmf_insert_mixed(vma, vaddr, pfn);

	if (IS_PRAMDISK(bdev))
		vma->vm_page_prot = old_prot;
	return ret;
}
